//Poner en la documentacion que se uso libxml2 para parsear los html
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libxml2/libxml/parser.h>
#include <libxml2/libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <ctype.h>
#include "parser_HTML.h"
#include "list.c"
//gcc `xml2-config --cflags --libs` -o xmlexample main.c

char * strReplace(const char *string, const char *substr, const char *replacement)
{
    char *tok = NULL;
    char *newstr = NULL;
    char *oldstr = NULL;

    //if either substr or replacement is NULL, duplicate string a let caller handle it
    if (substr == NULL || replacement == NULL) {
        return strdup (string);
    }

    newstr = strdup (string);

    while ((tok = strstr (newstr, substr))) {
        oldstr = newstr;
        newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) + 1 );
        //failed to alloc mem, free old string and return NULL
        if (newstr == NULL) {
            free (oldstr);
            return NULL;
        }

        memcpy ( newstr, oldstr, tok - oldstr );
        memcpy ( newstr + (tok - oldstr), replacement, strlen ( replacement ) );
        memcpy ( newstr + (tok - oldstr) + strlen( replacement ), tok + strlen ( substr ), strlen ( oldstr ) -strlen ( substr ) - ( tok - oldstr ) );
        memset ( newstr + strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) , 0, 1 );
        free (oldstr);
    }

    return newstr;
}

//int main( int argc, char **argv ){
char * establecerHTMLValido(char *strReplacePar)
{
    char *copiaStrReplace = strReplacePar;
    copiaStrReplace = strReplace(copiaStrReplace, "&excl;", "&#33;");
    copiaStrReplace = strReplace(copiaStrReplace, "&quot;", "&#34;");
    copiaStrReplace = strReplace(copiaStrReplace, "&num;", "&#35;");
    copiaStrReplace = strReplace(copiaStrReplace, "&dollar;", "&#36;");
    copiaStrReplace = strReplace(copiaStrReplace, "&percnt;", "&#37;");
    copiaStrReplace = strReplace(copiaStrReplace, "&amp;", "&#38;");
    copiaStrReplace = strReplace(copiaStrReplace, "&apos;", "&#39;");
    copiaStrReplace = strReplace(copiaStrReplace, "&lpar;", "&#40;");
    copiaStrReplace = strReplace(copiaStrReplace, "&rpar;", "&#41;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ast;", "&#42");
    copiaStrReplace = strReplace(copiaStrReplace, "&plus;", "&#43;");
    copiaStrReplace = strReplace(copiaStrReplace, "&comma;", "&#44;");
    copiaStrReplace = strReplace(copiaStrReplace, "&minus;", "&#45;");
    copiaStrReplace = strReplace(copiaStrReplace, "&hyphen;", "&#45;");
    copiaStrReplace = strReplace(copiaStrReplace, "&period;", "&#46;");
    copiaStrReplace = strReplace(copiaStrReplace, "&sol;", "&#47;");
    copiaStrReplace = strReplace(copiaStrReplace, "&colon;", "&#58;");
    copiaStrReplace = strReplace(copiaStrReplace, "&semi;", "&#59;");
    copiaStrReplace = strReplace(copiaStrReplace, "&lt;", "&#60;");
    copiaStrReplace = strReplace(copiaStrReplace, "&equals;", "&#61;");
    copiaStrReplace = strReplace(copiaStrReplace, "&gt;", "&#62;");
    copiaStrReplace = strReplace(copiaStrReplace, "&quest;", "&#63;");
    copiaStrReplace = strReplace(copiaStrReplace, "&commat;", "&#64;");
    copiaStrReplace = strReplace(copiaStrReplace, "&lsqb;", "&#91;");
    copiaStrReplace = strReplace(copiaStrReplace, "&bsol;", "&#92;");
    copiaStrReplace = strReplace(copiaStrReplace, "&rsqb;", "&#93;");
    copiaStrReplace = strReplace(copiaStrReplace, "&circ;", "&#94;");
    copiaStrReplace = strReplace(copiaStrReplace, "&lowbar;", "&#95;");
    copiaStrReplace = strReplace(copiaStrReplace, "&grave;", "&#96;");
    copiaStrReplace = strReplace(copiaStrReplace, "&lcub;", "&#123;");
    copiaStrReplace = strReplace(copiaStrReplace, "&verbar;", "&#124;");
    copiaStrReplace = strReplace(copiaStrReplace, "&rcub;", "&#125;");
    copiaStrReplace = strReplace(copiaStrReplace, "&tilde;", "&#126;");
    copiaStrReplace = strReplace(copiaStrReplace, "&hellip;", "&#133;");
    copiaStrReplace = strReplace(copiaStrReplace, "&dagger;", "&#134;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Dagger;", "&#135;");
    copiaStrReplace = strReplace(copiaStrReplace, "&lsquo;", "&#145;");
    copiaStrReplace = strReplace(copiaStrReplace, "&rsquo;", "&#146;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ldquo;", "&#147;");
    copiaStrReplace = strReplace(copiaStrReplace, "&rdquo;", "&#148;");
    copiaStrReplace = strReplace(copiaStrReplace, "&bull;", "&#149;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ndash;", "&#150;");
    copiaStrReplace = strReplace(copiaStrReplace, "&mdash;", "&#151;");
    copiaStrReplace = strReplace(copiaStrReplace, "&trade;", "&#153;");
    copiaStrReplace = strReplace(copiaStrReplace, "&nbsp;", "&#160;");
    copiaStrReplace = strReplace(copiaStrReplace, "&iexcl;", "&#161;");
    copiaStrReplace = strReplace(copiaStrReplace, "&cent;", "&#162;");
    copiaStrReplace = strReplace(copiaStrReplace, "&pound;", "&#163;");
    copiaStrReplace = strReplace(copiaStrReplace, "&curren;", "&#164;");
    copiaStrReplace = strReplace(copiaStrReplace, "&yen;", "&#165;");
    copiaStrReplace = strReplace(copiaStrReplace, "&brvbar;", "&#166;");
    copiaStrReplace = strReplace(copiaStrReplace, "&sect;", "&#167;");
    copiaStrReplace = strReplace(copiaStrReplace, "&uml;", "&#168;");
    copiaStrReplace = strReplace(copiaStrReplace, "&copy;", "&#169;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ordf;", "&#170;");
    copiaStrReplace = strReplace(copiaStrReplace, "&laquo;", "&#171;");
    copiaStrReplace = strReplace(copiaStrReplace, "&not;", "&#172;");
    copiaStrReplace = strReplace(copiaStrReplace, "&shy;", "&#173;");
    copiaStrReplace = strReplace(copiaStrReplace, "&reg;", "&#174;");
    copiaStrReplace = strReplace(copiaStrReplace, "&macr;", "&#175;");
    copiaStrReplace = strReplace(copiaStrReplace, "&deg;", "&#176;");
    copiaStrReplace = strReplace(copiaStrReplace, "&plusmn;", "&#177;");
    copiaStrReplace = strReplace(copiaStrReplace, "&sup2;", "&#178;");
    copiaStrReplace = strReplace(copiaStrReplace, "&sup3;", "&#179;");
    copiaStrReplace = strReplace(copiaStrReplace, "&acute;", "&#180;");
    copiaStrReplace = strReplace(copiaStrReplace, "&micro;", "&#181;");
    copiaStrReplace = strReplace(copiaStrReplace, "&para;", "&#182;");
    copiaStrReplace = strReplace(copiaStrReplace, "&middot;", "&#183;");
    copiaStrReplace = strReplace(copiaStrReplace, "&cedil;", "&#184;");
    copiaStrReplace = strReplace(copiaStrReplace, "&sup1;", "&#185;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ordm;", "&#186;");
    copiaStrReplace = strReplace(copiaStrReplace, "&raquo;", "&#187;");
    copiaStrReplace = strReplace(copiaStrReplace, "&frac14;", "&#188;");
    copiaStrReplace = strReplace(copiaStrReplace, "&frac12;", "&#189;");
    copiaStrReplace = strReplace(copiaStrReplace, "&frac34;", "&#190;");
    copiaStrReplace = strReplace(copiaStrReplace, "&iquest;", "&#191;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Agrave;", "&#192;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Aacute;", "&#193;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Acirc;", "&#194;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Atilde;", "&#195;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Auml;", "&#196;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Aring;", "&#197;");
    copiaStrReplace = strReplace(copiaStrReplace, "&AElig;", "&#198;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ccedil;", "&#199;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Egrave;", "&#200;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Eacute;", "&#201;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ecirc;", "&#202;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Euml;", "&#203;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Igrave;", "&#204;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Iacute;", "&#205;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Icirc;", "&#206;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Iuml;", "&#207;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ETH;", "&#208;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ntilde;", "&#209;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ograve;", "&#210;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Oacute;", "&#211;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ocirc;", "&#212;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Otilde;", "&#213;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ouml;", "&#214;");
    copiaStrReplace = strReplace(copiaStrReplace, "&times;", "&#215;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Oslash;", "&#216;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ugrave;", "&#217;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Uacute;", "&#218;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Ucirc;", "&#219;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Uuml;", "&#220;");
    copiaStrReplace = strReplace(copiaStrReplace, "&Yacute;", "&#221;");
    copiaStrReplace = strReplace(copiaStrReplace, "&THORN;", "&#222;");
    copiaStrReplace = strReplace(copiaStrReplace, "&szlig;", "&#223;");
    copiaStrReplace = strReplace(copiaStrReplace, "&agrave;", "&#224;");
    copiaStrReplace = strReplace(copiaStrReplace, "&aacute;", "&#225;");
    copiaStrReplace = strReplace(copiaStrReplace, "&acirc;", "&#226;");
    copiaStrReplace = strReplace(copiaStrReplace, "&atilde;", "&#227;");
    copiaStrReplace = strReplace(copiaStrReplace, "&auml;", "&#228;");
    copiaStrReplace = strReplace(copiaStrReplace, "&aring;", "&#229;");
    copiaStrReplace = strReplace(copiaStrReplace, "&aelig;", "&#230;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ccedil;", "&#231;");
    copiaStrReplace = strReplace(copiaStrReplace, "&egrave;", "&#232;");
    copiaStrReplace = strReplace(copiaStrReplace, "&eacute;", "&#233;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ecirc;", "&#234;");
    copiaStrReplace = strReplace(copiaStrReplace, "&euml;", "&#235;");
    copiaStrReplace = strReplace(copiaStrReplace, "&igrave;", "&#236;");
    copiaStrReplace = strReplace(copiaStrReplace, "&iacute;", "&#237;");
    copiaStrReplace = strReplace(copiaStrReplace, "&icirc;", "&#238;");
    copiaStrReplace = strReplace(copiaStrReplace, "&iuml;", "&#239;");
    copiaStrReplace = strReplace(copiaStrReplace, "&eth;", "&#240;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ntilde;", "&#241;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ograve;", "&#242;");
    copiaStrReplace = strReplace(copiaStrReplace, "&oacute;", "&#243;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ocirc;", "&#244;");
    copiaStrReplace = strReplace(copiaStrReplace, "&otilde;", "&#245;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ouml;", "&#246;");
    copiaStrReplace = strReplace(copiaStrReplace, "&divide;", "&#247;");
    copiaStrReplace = strReplace(copiaStrReplace, "&oslash;", "&#248;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ugrave;", "&#249;");
    copiaStrReplace = strReplace(copiaStrReplace, "&uacute;", "&#250;");
    copiaStrReplace = strReplace(copiaStrReplace, "&ucirc;", "&#251;");
    copiaStrReplace = strReplace(copiaStrReplace, "&uuml;", "&#252;");
    copiaStrReplace = strReplace(copiaStrReplace, "&yacute;", "&#253;");
    copiaStrReplace = strReplace(copiaStrReplace, "&thorn;", "&#254;");
    copiaStrReplace = strReplace(copiaStrReplace, "&yuml;", "&#255;");

    return copiaStrReplace;
}

#ifdef LIBXML_TREE_ENABLED

void obtenerHREFS(xmlNode * a_node)
{
    xmlNode *cur_node = NULL;
    xmlAttr *cur_attr = NULL;
    xmlNode *cur_val = NULL;

    for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
        if (cur_node->type == XML_ELEMENT_NODE) {
            if (!(strcmp(cur_node->name,"a"))) {
                //printf("node type: Element, name: %s\n", cur_node->name);
                for (cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
                    if (!(strcmp(cur_attr->name,"href"))) {
                        //printf("  -> with attribute : %s\n", cur_attr->name);
                        cur_val = cur_attr->children;
                        //printf("  -> with content : %s\n", cur_val->content);
                        //printf("Referencia %s\n", cur_val->content);

                        char tmp[strlen(cur_val->content) + 1];
                        
                        strcpy(tmp, (char*)cur_val->content);
                        
                        char *t = tmp;
                        if(refPaginaValida(t)){
                            insertar_url(t);
                        }
                    }
                }
            }
        }
        obtenerHREFS(cur_node->children);
    }
}

int concatenar(char *host, char *page)
{
    // declara e inicializa duas strings
    char new_host[strlen(host) + 1];
    char new_page[strlen(page) + 1];
    strcpy(new_host, host);
    strcpy(new_page, page);
    char *res = strcat(new_host, new_page);

    // exibe o resultado
    printf("%s\n\n", res);
    return 0;
}
/**
 * 
 * @param cadena
 * @param comienzo
 * @param longitud
 * @return 
 */
char* substr(char* cadena, int comienzo, int longitud)
{
    if (longitud == 0) {
        longitud = strlen(cadena)-comienzo-1;
    }

    char *nuevo = (char*)malloc(sizeof(char) * longitud);

    strncpy(nuevo, cadena + comienzo, longitud);

    return strndup(nuevo, longitud);
}

char* substring(const char* str, size_t begin, size_t len)
{
  if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len))
    return 0;

  return strndup(str + begin, len);
} 
//retorno --> 1: referencia a pagina valida, 0: referencia a pagina no valida
//funciona para archivos .htm y .html
int refPaginaValida(char *strRefPagina)
{
    if (strlen(strRefPagina) > 5) {
        if (!strcasecmp((substr(strRefPagina, strlen(strRefPagina) - 5, 5)), ".html") ||
            !strcasecmp((substr(strRefPagina, strlen(strRefPagina) - 4, 4)), ".htm"))
            {
               return 1;
            }
            else 
            {
                return 0;
            }
    }
    else
    {
        return 0;
    }
}

/**
 * Parsea el archivo HTML descargado
 */
void parserHTML(char * archivoHTML)
{
    xmlDoc *doc = NULL;
    xmlNode *root_element = NULL;

    /*
     * this initialize the library and check potential ABI mismatches
     * between the version it was compiled for and the actual shared
     * library used.
     */
    LIBXML_TEST_VERSION

    //parse the file and get the DOM
    doc = xmlReadFile(archivoHTML, NULL, 1);

    if (doc == NULL) {
        printf("error: could not parse file %s\n", archivoHTML);
    }

    //get the root element node
    root_element = xmlDocGetRootElement(doc);

    obtenerHREFS(root_element);

    //free the document
    xmlFreeDoc(doc);

    //free the global variables that may have been allocated by the parser
    xmlCleanupParser();

    //return 0;
}

#else
void parserHTML(void) {
    fprintf(stderr, "Tree support not compiled in\n");
    //exit(1);
}
#endif

/**
 * Crea una lista de direcciones
 * @param newdireccion
 */
/*
void insertar_url(char *url)
{
    PAGE *newpage;
    if ((newpage = malloc(sizeof(PAGE))) == NULL) { 
        abort(); 
    }
    else
    {        
        newpage->url = strdup(url);
        newpage->siguiente = NULL;
        if(!head){
            head = newpage;
        }
        else
        {
            PAGE *tmp;
            tmp = head;
            while(tmp->siguiente != NULL){
                tmp = tmp->siguiente;
            }
            tmp->siguiente = newpage;
            
        }
    }
}
*/

/**
 * Imprime el contenido de la lista
 */
void imprime_links()
{
    PAGE *pagina;
    pagina = head;
    
    while(pagina)
    {
        printf("LISTA: %s\n", pagina->url);
        pagina = pagina->siguiente;
    }
    //free(pagina);

}


char *trim(char *s) {
    char *ptr;
    if (!s)
        return NULL;   // handle NULL string
    if (!*s)
        return s;      // handle empty string
    for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); --ptr);
    ptr[1] = '\0';
    return s;
}


int main()
{
/*
    parserHTML("deportes.html");
    
    PAGE *pagina;
    pagina = head;
    
    while(pagina)
    {
        printf("%s\n",pagina->url);
        pagina = pagina->siguiente;
    }
*/
    concatenar("www.aldia.com", "/deportes.html");
}